#include "KamaCoder.h"
using namespace std;

// 深度优先搜索函数，用于遍历网格
void KamaCoder103::dfs(const vector<vector<int>>& grid,
                       vector<vector<bool>>& visited, int x, int y) {
  // 如果该点已经遍历过，则直接返回
  if (visited[x][y] == true) return;

  visited[x][y] = true;
  // 遍历四个方向
  for (int i = 0; i < 4; i++) {
    int nextx = x + dir[i][0];
    int nexty = y + dir[i][1];
    // 越界检查
    if (nextx < 0 || nexty < 0 || nextx >= grid.size() ||
        nexty >= grid[0].size())
      continue;
    // 反过来的话就是水向高处流
    if (grid[x][y] < grid[nextx][nexty]) {
      dfs(grid, visited, nextx, nexty);
    }
  }
}

int KamaCoder103::run() {
  int n, m;
  cin >> n >> m;
  vector<vector<int>> grid(n, vector<int>(m));
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> grid[i][j];
    }
  }
  // 标记从第一组边界上的节点出发，可以遍历的节点
  vector<vector<bool>> firstvisited(n, vector<bool>(m, false));
  // 标记从第二组边界上的节点出发，可以遍历的节点
  vector<vector<bool>> secondvisited(n, vector<bool>(m, false));

  // 从最左和最右的节点出发，向高处遍历
  for (int i = 0; i < n; i++) {
    dfs(grid, firstvisited, i, 0);       // 遍历最左列
    dfs(grid, secondvisited, i, m - 1);  // 遍历最右列
  }
  // 从最上和最下行的节点出发，向高处遍历
  for (int j = 0; j < m; j++) {
    dfs(grid, firstvisited, 0, j);       // 遍历最下行
    dfs(grid, secondvisited, n - 1, j);  // 遍历最上行
  }

  // 输出
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (firstvisited[i][j] == true && secondvisited[i][j] == true)
        cout << i << " " << j << endl;
      ;
    }
  }
  return 0;
}